#define StrNum 20
#define Type 20
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <iostream>
#include <iomanip>
#include <string>
#include<string.h>
#include <fstream>                  //输入/输出文件流类
using namespace std;
const int Maxb=100;                 //最多可存储的图书


    int sock_fd,client_fd;    /*sock_fd：监听socket；client_fd：数据传输socket */
    int sin_size;
    char buffer[8];
    struct sockaddr_in my_addr;    /* 本机地址信息 */
    struct sockaddr_in remote_addr;    /* 客户端地址信息 */

char waitForInput(){
	if(0){
		char input;
		cin>>input;
		return input;
	}else{
		read(client_fd, buffer, 8);
		return buffer[0];
	}
	
}


class Book
{
private:
    int tag;                        //删除标记
	int num;                        //图书编号
	int add;                        //增加标记
	char number[StrNum];            //编号
	char name[StrNum];              //书名
	char kind[Type];                //图书类型

public:
	Book(){}
	char getkind()                  //获取图书类型
	{
		return kind[Type];
	}                                
	char getname()	                //获取书名
	{ 
		return name[StrNum]; 
	}
	int getnum()                     //获取图书编号
	{ 
		return num; 
	}                  
	int gettag()                    //获取删除标记
	{ 
		return tag;
	}
	void setname(char na[])         //设置书名
	{
		strcpy(name,na);
	}
	void setkind(char kin[])        //设置类型
	{
		strcpy(kind,kin);
	}
	void delbook()                  //删除图书
	{
		tag=1;
	}
	void addbook(int n,char *na,char *kin)    //增加图书
	{
		tag=0;
		num=n;
		strcpy(name,na);
		strcpy(kind,kin);
	}
	void disp()                     //输出图书		
	{
		cout.flags (ios::left);     //设置对齐的标志位为左
		cout<<setw(15)<<num<<setw(20)<<name<<setw(15)<<kind<<endl;		
	}		
};

class BDatabase
{
private:
    int top;                        //图书记录指针
	Book book[Maxb];                //图书记录
public:
	BDatabase()                     //构造函数，将book.txt读到book[]中
	{ 
			Book b;
			top=-1;
			fstream file("book.txt",ios::in);
			while (1)
			{
				file.read((char *)&b,sizeof(b));
				if (!file) break;
				top++;
				book[top]=b;
			}
			file.close();
	} 
	void clear()                    //全删
	{
		top=-1;
	}
    int addbook(int n,char *na,char *kin)     //增加图书
	{
		Book *p=query(n);
		if(NULL==p)
		{
			top++;
			book[top].addbook(n,na,kin);
			return 1;
		}
		return 0;
	}
	Book *query(int bookid)         //查找图书
	{
		for (int i=0;i<=top;i++)
			if (book[i].getnum()==bookid &&book[i].gettag()==0)
			{	
				return &book[i];
			}
			return NULL;
	}
	void bookdata();                //图书库
	void disp()
	{
	  for (int i=0;i<=top;i++)
		  if (book[i].gettag()==0)
			  book[i].disp();
	}
	~BDatabase()                    //析构函数，将book[]写到book.txt文件中
	{
		fstream file("book.txt",ios::out);
        for (int i=0;i<=top;i++)
			if (book[i].gettag()==0)
				file.write((char *)&book[i],sizeof(book[i]));
			file.close();
	}
};
void BDatabase::bookdata()
{
    char choice;
	char bname[40];
	char bkind[40];
	char newType[20];
	int bookid;
	Book *b;
	while (choice!='0')
	{   
	    cout<<"\t******************************************************************\n";
		cout<<"                                           \n\n";
		cout<<"\t\t\t图  书  管  理  系  统\n\n";
		cout<<"\t\t\t1    新增图书记录\n";
        cout<<"\t\t\t2    更改图书记录\n";
        cout<<"\t\t\t3    删除图书记录\n";
		cout<<"\t\t\t4    查找图书记录\n";
		cout<<"\t\t\t5    显示图书记录\n";
		cout<<"\t\t\t6    清空全部记录（慎用）\n";
		cout<<"\t\t\t0    退出系统\n";
		cout<<"                                           \n\n";
		cout<<"\t******************************************************************\n";
        cout<<"请选择(1,2,3,4,5,6,0):";
		//cin>>choice;
		
		choice = waitForInput();
		cout<<"inpug inpug inpug....."<<endl;
		switch (choice)
		{
            case '1':
				cout<<"输入图书编号:"<<endl;
				cin>>bookid;
				cout<<"输入图书类型:"<<endl;
				cin>>newType;
                cout<<"输入图书书名:"<<endl;
				cin>>bname;
				addbook(bookid,bname,newType);
				break;
            case '2':
				cout<<"输入图书编号:"<<endl;
				cin>>bookid;
				b=query(bookid);
				if(b==NULL)
				{
					cout<<"该图书不存在"<<endl;
				    break;
				}
				cout<<"输入新的书名:"<<endl;
				cin>>bname;
				b->setname(bname);
				cout<<"输入新的类型:"<<endl;
				cin>>bkind;
				b->setkind(bkind);
			 	break;
            case '3':
				   	cout<<"读入图书编号:"<<endl;
					cin>>bookid;
					b=query(bookid);
					if(b==NULL)
					{
					    cout<<"该图书不存在"<<endl;
					    break;
					}
					char tg1;
					cout<<"确定要删除此记录吗?(Y/N)"<<endl;
					cin>>tg1;
					if(tg1!='n'&&tg1!='N')
					{
					b->delbook();
					cout<<"已成功删除该书记录！"<<endl;
					break;
					}		
			case '4':
				cout<<"读入图书编号:"<<endl;
				cin>>bookid;
				b=query(bookid);
				if (b==NULL)
				{
					cout<<"该图书不存在"<<endl;
					break;
				}	
				cout<<"图书编号      图书名称            图书类型         \n";
				b->disp();
				break;
			case '5':
				cout<<"图书编号      图书名称            图书类型         \n";
				disp();
				break;
			case '6':
				    char tg2;
					cout<<"确定要清空所有记录吗?(Y/N)"<<endl;
					cin>>tg2;
					if(tg2!='n'&&tg2!='N')
					{
					clear();
				    cout<<"已成功清空记录！"<<endl;
					break;
					}
			case '0':
				break;
			default:cout<<"输入错误，请从新输入(数字为0~6):";
		}
	}
}
//main() 函数的实现，程序的主界面的引导
int main()
{    
	//Library的
	char choice;
	BDatabase BookDB;



    if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket创建出错！");
        exit(1);
    }
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(4343); // port number
    my_addr.sin_addr.s_addr = INADDR_ANY;
    bzero(&(my_addr.sin_zero),8);
    if(bind(sock_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
        perror("bind出错！");
        exit(1);
    }
    if(listen(sock_fd, 10) == -1) { // max connect number
        perror("listen出错！");
        exit(1);
    }

    while(1) {
        sin_size = sizeof(struct sockaddr_in);
        if((client_fd = accept(sock_fd, (struct sockaddr *)&remote_addr, (socklen_t*)&sin_size)) == -1) {
            perror("accept出错");
            continue;
        }
        printf("received a connection from %s\n", inet_ntoa(remote_addr.sin_addr));
        if(!fork()) {    /* 子进程代码段 */
            if(send(client_fd, "Hello, you are connected!\n", 26, 0) == -1) {
                perror("send出错！");
            }
	    
	    while(1){


		//Library的
	        cout<<"\t******************************************************************\n";
	        cout<<"                                           \n\n";
		    cout<<"\n\n\t\t\t欢迎使用图书管理系统\n\n";
			cout<<endl<<endl<<"\t\t\t图  书  管  理  系  统\n\n\n\n";
			cout<<setw(83)<<"by tobe\n\n\n\n";
			cout<<"                                           \n\n";
			cout<<"\t******************************************************************\n";

		    
			cout<<"\t\t\t1    进  入  系  统\n\n\t\t\t0    离       开"<<endl;
			cout<<"请选择:";

			//cin>>choice;
		    	read(client_fd, buffer, 8);
		    	cout<<endl<<"XXXXXOOOOOOOOXXXXx : "<<buffer<<endl;
			
			choice = buffer[0];
			switch(choice)
			{
			case '1':
					BookDB.bookdata();
					break; 
            		case '0':
				 cout<<"\n\n\t\t\t退出程序！！欢迎再次使用！！！！\n\n"<<endl<<endl<<endl;
				 
				 break;
			default:cout<<"输入错误，请从新输入：";
			}




	   	 if(buffer[0]=='*'){
			cout<<"drop the connection"<<endl;
	    		close(client_fd);
	    		exit(0);	
	  	  }	
	    }	
        }
        close(client_fd);
    }
	return 0;
}


